/**
 * 
 */
package com.itinsys.enma.dao.impl;

import java.sql.Time;
import java.util.ArrayList;
import java.util.List;

import net.sf.ehcache.ObjectExistsException;

import org.apache.log4j.Logger;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.type.Type;

import com.itinsys.enma.dao.DBTemplate;
import com.itinsys.enma.dao.ShiftDAO;
import com.itinsys.enma.dao.hibernate.DBObject;
import com.itinsys.enma.domain.PriorityEnvironment;
import com.itinsys.enma.domain.Shift;

/**
 * @author pferraz
 *
 */
public class ShiftDAOImpl implements ShiftDAO {

	private static Logger logger=Logger.getLogger("dao");
	/* (non-Javadoc)
	 * @see com.itinsys.enma.dao.ShiftDAO#getById(java.lang.String)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public Shift getById(String shiftId) throws ObjectExistsException {
		List<Shift> result=null;
		Session sess=null;
		try{
			sess=DBTemplate.getConnTemplate().getSessionFactory().openSession();
			Query q=sess.createQuery("from s in class com.itinsys.enma.domain.Shift where s.id=?");
			q.setParameters(new Object[]{shiftId}, new Type[]{Hibernate.STRING});
			result=q.list();
			if(result.isEmpty()){
				throw new ObjectExistsException("El turno ingresado no existe");	
			}
		}catch(HibernateException e){
			logger.error("Error al buscar turno por identificador. " ,e);
		}finally {
            if (sess != null){
            	sess.close();	
            }
        }
		return result.get(0);
	}
	
	
	/* (non-Javadoc)
	 * @see com.itinsys.enma.dao.ShiftDAO#getById(java.lang.String)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<Shift> getAll() throws ObjectExistsException {
		List<Shift> result=null;
		Session sess=null;
		try{
			sess=DBTemplate.getConnTemplate().getSessionFactory().openSession();
			Query q=sess.createQuery("from s in class com.itinsys.enma.domain.Shift");
			result=q.list();
			if(result.isEmpty()){
				throw new ObjectExistsException("El turno ingresado no existe");	
			}
		}catch(HibernateException e){
			logger.error("Error al buscar turno por identificador. " ,e);
		}finally {
            if (sess != null){
            	sess.close();	
            }
        }
		return result;
	}


	@SuppressWarnings("unchecked")
	@Override
	public Shift getShiftByHourRange(Time startHour, Time endHour) throws ObjectExistsException{
		List<Shift> result=null;
		Session sess=null;
		try{
			sess=DBTemplate.getConnTemplate().getSessionFactory().openSession();
			Query q;
			if(startHour!=null && endHour!=null){
				q=sess.createQuery("from s in class com.itinsys.enma.domain.Shift where s.startTime<=? and s.endTime>=?");
				q.setParameters(new Object[]{startHour,endHour}, new Type[]{Hibernate.TIME,Hibernate.TIME});
			}else if(startHour!=null && endHour==null){
				q=sess.createQuery("from s in class com.itinsys.enma.domain.Shift where s.startTime=(select min(sh.startTime) from com.itinsys.enma.domain.Shift sh where sh.endTime>=? and sh.startTime<=?)");
				q.setParameters(new Object[]{startHour,startHour}, new Type[]{Hibernate.TIME,Hibernate.TIME});
			}else{
				q=sess.createQuery("from s in class com.itinsys.enma.domain.Shift where s.startTime=(select max(sh.startTime) from com.itinsys.enma.domain.Shift sh where sh.startTime<=? and sh.endTime>=?)");
				q.setParameters(new Object[]{endHour,endHour}, new Type[]{Hibernate.TIME,Hibernate.TIME});
			}
			result=q.list();
			if(result.isEmpty()){
				throw new ObjectExistsException("El turno ingresado no existe");	
			}
		}catch(HibernateException e){
			logger.error("Error al buscar turno por identificador. " ,e);
		}finally {
            if (sess != null){
            	sess.close();	
            }
        }
		return result.get(0);
	}


	@Override
	public boolean addShift(Shift shift) {
		
		return DBObject.addObject(shift);
	}


	@Override
	public boolean updateShift(Shift shift) {
		
		return DBObject.updateObject(shift);
	}


	@Override
	public boolean deleteShift(Shift shift) {
		
		return DBObject.removeObject(shift);
	}


	@SuppressWarnings("unchecked")
	@Override
	public List<PriorityEnvironment> getPriorityEnvironmentByShifts(int id) {
		Session sess = null;
		Query query=null;
		List<PriorityEnvironment> result = new ArrayList<PriorityEnvironment>();
		try {
			sess = DBTemplate.getConnTemplate().getSessionFactory().openSession();
			query = sess.createQuery("from p in class com.itinsys.enma.domain.PriorityEnvironment where p.shift.id=?");
			query.setParameters(new Object[] {id}, new Type[] {Hibernate.INTEGER});
			result = query.list();
			
		} catch (HibernateException e) {
			logger.error("Error al buscar reservas por salon", e);
		} finally {
			if (sess != null) {
				sess.close();
			}

		}
		return result;
	}


	@SuppressWarnings("unchecked")
	@Override
	public Shift getByDesc(String description) {
		List<Shift> result=null;
		Session sess=null;
		try{
			sess=DBTemplate.getConnTemplate().getSessionFactory().openSession();
			Query q=sess.createQuery("from s in class com.itinsys.enma.domain.Shift where s.description=?");
			q.setParameters(new Object[]{description}, new Type[]{Hibernate.STRING});
			result=q.list();
			if(result.isEmpty()){
				throw new ObjectExistsException("El turno ingresado no existe");	
			}
		}catch(HibernateException e){
			logger.error("Error al buscar turno por identificador. " ,e);
		}finally {
            if (sess != null){
            	sess.close();	
            }
        }
		return result.get(0);
	}


	@SuppressWarnings("unchecked")
	@Override
	public boolean validateShiftRange(int id,Time startTime, Time endTime) {
		List<Shift> result=null;
		Session sess=null;
		try{
			sess=DBTemplate.getConnTemplate().getSessionFactory().openSession();
			Query q=sess.createQuery("from s in class com.itinsys.enma.domain.Shift where ? <s.endTime and ? > s.startTime and id!=?");
			q.setParameters(new Object[]{startTime,endTime,id}, new Type[]{Hibernate.TIME,Hibernate.TIME,Hibernate.INTEGER});
			result=q.list();
			if(result.isEmpty()){
				return true;	
			}
		}catch(HibernateException e){
			logger.error("Error al buscar turno por identificador. " ,e);
		}finally {
            if (sess != null){
            	sess.close();	
            }
        }
		return false;
	}

}
